﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Linq.Expressions;

namespace IntelliLance.Math.Parser
{
    public static class InputHelpers
    {
        public static void DefineFunction(this FunctionsDictionary funcs, 
            string identifier, MethodInfo method)
        {
            funcs.Add(identifier, new FunctionDefinition(identifier, method, funcs.Comparer as StringComparer));
        }

        public static void DefineFunction(this FunctionsDictionary funcs,
            string identifier, Delegate method)
        {
            funcs.Add(identifier, new FunctionDefinition(identifier, method, funcs.Comparer as StringComparer));
        }

        public static void DefineFunction<TOutput>(this FunctionsDictionary funcs,
            string identifier,
            Expression<Func<TOutput>> func)
            where TOutput : struct, IConvertible, IComparable
        {
            funcs.Add(identifier, new FunctionDefinition(identifier, func, funcs.Comparer as StringComparer));
        }

        public static void DefineFunction<TInput, TOutput>(this FunctionsDictionary funcs,
            string identifier,
            Expression<Func<TInput, TOutput>> func)
            where TInput : struct, IConvertible, IComparable
            where TOutput : struct, IConvertible, IComparable
        {
            funcs.Add(identifier, new FunctionDefinition(identifier, func, funcs.Comparer as StringComparer));
        }

        public static void DefineFunction<TInput1, TInput2, TOutput>(this FunctionsDictionary funcs,
            string identifier,
            Expression<Func<TInput1, TInput2, TOutput>> func)
            where TInput1 : struct, IConvertible, IComparable
            where TInput2 : struct, IConvertible, IComparable
            where TOutput : struct, IConvertible, IComparable
        {
            funcs.Add(identifier, new FunctionDefinition(identifier, func, funcs.Comparer as StringComparer));
        }

        public static void DefineFunction<TInput1, TInput2, TInput3, TOutput>(this FunctionsDictionary funcs,
            string identifier,
            Expression<Func<TInput1, TInput2, TInput3, TOutput>> func)
            where TInput1 : struct, IConvertible, IComparable
            where TInput2 : struct, IConvertible, IComparable
            where TInput3 : struct, IConvertible, IComparable
            where TOutput : struct, IConvertible, IComparable
        {
            funcs.Add(identifier, new FunctionDefinition(identifier, func, funcs.Comparer as StringComparer));
        }

        public static void DefineFunction<TInput1, TInput2, TInput3, TInput4, TOutput>(this FunctionsDictionary funcs,
            string identifier,
            Expression<Func<TInput1, TInput2, TInput3, TInput4, TOutput>> func)
            where TInput1 : struct, IConvertible, IComparable
            where TInput2 : struct, IConvertible, IComparable
            where TInput3 : struct, IConvertible, IComparable
            where TInput4 : struct, IConvertible, IComparable
            where TOutput : struct, IConvertible, IComparable
        {
            funcs.Add(identifier, new FunctionDefinition(identifier, func, funcs.Comparer as StringComparer));
        }

    }
}
